package sandbox.swing;

// GlassExample.java
// Show how a glass pane can be used to block mouse and key events.  This
// version reflects suggestions made by readers after the book was published.
// (A special thanks to Mark Hansen for his correspondence on this issue.)  A
// further enhancement would be to make a custom subclass of JPanel that hides
// these events at a lower level, but this will do for now.
//
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class GlassExample extends JFrame {

    GlassPanel glass;
    Timer timer;

    public GlassExample() {
        super("GlassPane Demo");
        setSize(500, 300);
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        // Set up the glass pane with a little message and a progress bar...
        glass = new GlassPanel();
        setGlassPane(glass);

        // Now set up a few buttons & images for the main application
        JPanel mainPane = new JPanel();
        mainPane.setBackground(Color.white);
        JButton redB = new JButton("Red");
        JButton blueB = new JButton("Blue");
        JButton greenB = new JButton("Green");
        mainPane.add(redB);
        mainPane.add(greenB);
        mainPane.add(blueB);
        mainPane.add(new JLabel(new ImageIcon("oreilly.gif")));

        // Attach the popup debugger to the main app buttons so you
        // see the effect of making a glass pane visible
        PopupDebugger pd = new PopupDebugger(this);
        redB.addActionListener(pd);
        greenB.addActionListener(pd);
        blueB.addActionListener(pd);

        // And last but not least, our button to launch the glass pane
        JButton startB = new JButton("Start the big operation!");
        startB.addActionListener(new ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent A) {
                glass.setVisible(true);
                glass.focus();  // required to trap key events
                ProgressContext ctx = new ProgressContext();
                ctx.glass = glass;
                ctx.progressStart = 0;
                ctx.progressEnd = 100;
                startTimer2(ctx);
//                startTimer();
/*                EventQueue.invokeLater(new Runnable() {

                    public void run() {
                        ProgressContext ctx = new ProgressContext();
                        ctx.glass = glass;
                        ctx.progressStart = 0;
                        ctx.progressEnd = 100;
                        routine(ctx);
                        glass.setVisible(false);
                    }
                });*/
            }
        });

        Container contentPane = getContentPane();
        contentPane.add(mainPane, BorderLayout.CENTER);
        contentPane.add(startB, BorderLayout.SOUTH);
    }

    public void startTimer2(final ProgressContext ctx) {
        final Timer timer2 = new Timer(0, new ActionListener() {

            public void actionPerformed(ActionEvent A) {
                routine(ctx);
                glass.setVisible(false);
            }
        });
        timer2.setRepeats(false);
        timer2.start();
    }

    // A quick method to start up a 10 second timer and update the
    // progress bar
    public void startTimer() {
        if(timer == null) {
            timer = new Timer(250, new ActionListener() {
                int progress = 0;

                public void actionPerformed(ActionEvent A) {
                    progress += 10;
                    glass.update(progress);

                    // Once we hit 100%, remove the glass pane and reset the
                    // progress bar stuff
                    if(progress >= 100) {
                        progress = 0;
                        timer.stop();
                        glass.setVisible(false);
                        glass.update(0);
                    }
                }
            });
        }
        if(timer.isRunning()) {
            timer.stop();
        }
        timer.start();
    }

    // A graphical debugger that pops up anytime a button is pressed
    public class PopupDebugger implements ActionListener {

        private JFrame parent;

        public PopupDebugger(JFrame f) {
            parent = f;
        }

        public void actionPerformed(ActionEvent ae) {
            JOptionPane.showMessageDialog(parent, ae.getActionCommand());
        }
    }

    private void routine(ProgressContext progressCtx) {
        int start = progressCtx.progressStart;
        int end = progressCtx.progressEnd;
        for(int pc = 0; pc < 100; pc += 10) {
            try {
                Thread.sleep(250);
            } catch(InterruptedException ex) {
            }
            if(progressCtx != null) {
                progressCtx.glass.update(start + (end - start) * pc / 100);
            }
        }
    }

    public static void main(String[] args) {
        GlassExample ge = new GlassExample();
        ge.setVisible(true);
    }
}
